home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / samples / midpnt / midpnt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-25  |  33.4 KB  |  1,203 lines

  1. /*       MidpNT.cpp
  2.  *
  3.  * MIDAS Module Player for Windows NT main program file
  4.  *
  5.  * $Id: MidpNT.cpp 1.15 1997/01/25 13:17:44 pekangas Exp $
  6.  *
  7.  * Copyright 1996 Petteri Kangaslampi
  8. */
  9.  
  10. #include <windows.h>
  11. #include <ddeml.h>
  12. #include <stdio.h>
  13. #include <malloc.h>
  14. #include <stdlib.h>
  15. #include "midpres.h"
  16. #include "midasdll.h"
  17. #include "MidpNT.h"
  18. #include "MidpList.h"
  19. #include "MidpModeless.h"
  20. #include "MidpView.h"
  21. #include "SongInfo.h"
  22. #include "InstList.h"
  23. #include "ViewList.h"
  24. #include "Archivers.h"
  25. #include "Registry.h"
  26.  
  27. #define POLLRATE 100
  28.  
  29. #define NUMLINES 100
  30. #define MAXLINE 255
  31.  
  32. #define MIDP_ADDTEXT WM_USER+100
  33.  
  34. HANDLE          instance;               /* program instance */
  35.  
  36. static char     *mainWinClass = "midpNTClass";  /* main window class name */
  37.  
  38. HWND            mainWinHandle;
  39. HWND            editWinHandle;
  40. int             editWidth, editHeight;
  41. HANDLE          accelHandle;
  42.  
  43. static char     *textLines[NUMLINES];   /* all text lines */
  44. static char     *text;
  45. static int      numLines;
  46. static char     loadFileName[MAX_PATH + 16];    /* fudge factor */
  47.  
  48. MIDASmodule     module = NULL;
  49.  
  50. char            defaultDir[MAX_PATH];
  51. char            unzipDir[MAX_PATH];
  52.  
  53. LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT message, WPARAM wparam,
  54.     LPARAM lparam);
  55. void StartDDEServer(void);
  56. void PlayFile(char *fileName);
  57. int PlayDDE(char *fileName);
  58. void ReadRegistry(void);
  59. void WriteRegistry(void);
  60. void RestoreMainWindow(void);
  61. void SaveViews(void);
  62. void RestoreViews(void);
  63.  
  64.  
  65.  
  66. DWORD           ddeInstance;
  67. int             ddeInit = 0;
  68.  
  69. SongInfoView    *songInfoView = NULL;
  70. InstListView    *instListView = NULL;
  71.  
  72. midpList        midpModelessList;
  73. midpViewWindowList viewWindowList;
  74. midpViewList    viewList;
  75.  
  76. char            *iniFile = "MidpNT.ini";
  77. char            *defaultDirectory = "";
  78.  
  79. char            *baseKey = "Software\\Sahara Surfers\\MidpNT";
  80.  
  81. static int      mainWinX, mainWinY, mainWinWidth, mainWinHeight;
  82.  
  83. int             viewsChildren = 1;
  84.  
  85. int             minimalUI = 0;
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93. /****************************************************************************\
  94. *
  95. * Function:     int WinMain(HANDLE thisInstance, HANDLE prevInstance, LPSTR
  96. *                   commandLine, int showCommand);
  97. *
  98. * Description:  Windows main function - common initialization and message loop
  99. *
  100. \****************************************************************************/
  101.  
  102. int WINAPI WinMain(HANDLE thisInstance, HANDLE prevInstance,
  103.     LPSTR commandLine, int showCommand)
  104. {
  105.     MSG         msg;
  106.     WNDCLASS    wc;
  107.     midpModeless *modeless;
  108.     char        *c, *d, *end;
  109.     int         inQuotes = 0;
  110.     int         hadCharacters = 0;
  111. //    char        kala[256];
  112.  
  113.     prevInstance = prevInstance;
  114.  
  115.     StartupMIDAS();
  116.  
  117. //    sprintf(kala, "commandLine: \"%s\"", commandLine);
  118. //    MessageBox(NULL, kala, "Kala", MB_OK);
  119.  
  120.     /* Build file name to load: */
  121. //    strcpy(loadFileName, commandLine);
  122.     loadFileName[0] = 0;
  123.     if ( strlen(commandLine) > 0 )
  124.     {
  125.         c = commandLine;
  126.  
  127.         while ( (*c != 0) && (isspace(*c)) )
  128.             c++;
  129.  
  130.         if ( *c == '-' )
  131.         {
  132.             c++;
  133.  
  134.             switch ( *(c++) )
  135.             {
  136.                 case 'm':
  137.                     minimalUI = 1;
  138.                     break;
  139.             }
  140.  
  141.             while ( (*c != 0) && (!isspace(*c)) )
  142.                 c++;
  143.         }
  144.  
  145.         d = loadFileName;
  146.         end = d;
  147.  
  148.         while ( *c != 0 )
  149.         {
  150.             if ( *c == '\"' )
  151.             {
  152.                 inQuotes ^= 1;
  153.                 hadCharacters = 1;
  154.             }
  155.             else
  156.             {
  157.                 if ( (*c == ' ') && (!hadCharacters) )
  158.                 {
  159.                     c++;
  160.                     continue;
  161.                 }
  162.  
  163.                 *(d++) = *c;
  164.  
  165.                 if ( inQuotes || (*c != ' ') )
  166.                     end = d;
  167.  
  168.                 hadCharacters = 1;
  169.             }
  170.             c++;
  171.         }
  172.  
  173.         *end = 0;
  174.     }
  175.  
  176. //    sprintf(kala, "loadFileName: \"%s\"", loadFileName);
  177. //    MessageBox(NULL, kala, "Kala", MB_OK);
  178.  
  179.     instance = thisInstance;
  180.  
  181.     if ( PlayDDE(loadFileName) )
  182.         return 0;
  183.  
  184.     /* This is the first instance - now set up a DDE server: */
  185.     StartDDEServer();
  186.  
  187.     /* Let's be a Very Important Process: */
  188.     SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  189.  
  190.     ReadRegistry();
  191.  
  192.     songInfoView = new SongInfoView;
  193.     viewList.AddView(songInfoView);
  194.     instListView = new InstListView;
  195.     viewList.AddView(instListView);
  196.  
  197.     /* Set up and register window class for the main window: */
  198.     wc.style = CS_HREDRAW | CS_VREDRAW;
  199.     wc.lpfnWndProc = mainWindowProc;
  200.     wc.cbClsExtra = 0;
  201.     wc.cbWndExtra = sizeof(DWORD);
  202.     wc.hInstance = instance;
  203.     wc.hIcon = LoadIcon(instance, "MIDP_ICON");
  204.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  205.     //wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  206.     wc.hbrBackground = NULL;
  207.     wc.lpszMenuName = "MAINMENU";
  208.     wc.lpszClassName = mainWinClass;
  209.     if ( RegisterClass(&wc) == 0 )
  210.         return FALSE;
  211.  
  212.     if ( !minimalUI )
  213.         RestoreMainWindow();
  214.     else
  215.     {
  216.         mainWinX = mainWinY = 100;
  217.         mainWinWidth = 320;
  218.         mainWinHeight = 0;
  219.     }
  220.  
  221.     /* Create main window: */
  222.  
  223.     mainWinHandle = CreateWindow(
  224.         mainWinClass,                           /* class */
  225.         "MIDAS Module Player for Windows NT",   /* caption */
  226.         WS_OVERLAPPEDWINDOW,                    /* style */
  227.         mainWinX,                               /* init. x pos */
  228.         mainWinY,                               /* init. y pos */
  229.         mainWinWidth,                           /* init. x size */
  230.         mainWinHeight,                          /* init. y size */
  231.         NULL,                                   /* parent window */
  232.         NULL,                                   /* menu handle */
  233.         instance,                               /* program handle */
  234.         NULL                                    /* create parms */
  235.     );
  236.  
  237.     if ( !mainWinHandle )
  238.         return FALSE;
  239.  
  240.     if ( (accelHandle = LoadAccelerators(instance, "MAINACCELERATORS")) ==
  241.         NULL )
  242.     {
  243.         MessageBox(NULL, "Coulnd't load accelerators", "MidpNT Initialization error",
  244.             MB_OK | MB_ICONEXCLAMATION);
  245.  
  246.         return FALSE;
  247.     }
  248.  
  249.     /* Display main window: */
  250.     ShowWindow(mainWinHandle, showCommand);
  251.     UpdateWindow(mainWinHandle);
  252.  
  253.     if ( !minimalUI )
  254.         RestoreViews();
  255.  
  256.     /* Da Message Loop: */
  257.     while ( GetMessage(&msg, NULL, NULL, NULL) )
  258.     {
  259.         if ( !TranslateAccelerator(mainWinHandle, accelHandle, &msg) )
  260.         {
  261.             modeless = (midpModeless*) midpModelessList.GetFirst();
  262.             while ( modeless != NULL )
  263.             {
  264.                 if ( IsDialogMessage(modeless-> hwnd, &msg) )
  265.                     break;
  266.                 modeless = (midpModeless*) midpModelessList.GetNext();
  267.             }
  268.  
  269.             if ( modeless == NULL )
  270.             {
  271.                 TranslateMessage (&msg) ;
  272.                 DispatchMessage (&msg) ;
  273.             }
  274.         }
  275.     }
  276.  
  277.     WriteRegistry();
  278.  
  279.     if ( ddeInit )
  280.         DdeUninitialize(ddeInstance);
  281.  
  282.     return(msg.wParam);
  283. }
  284.  
  285.  
  286. void RestoreViews(void)
  287. {
  288.     int         i, n;
  289.     Registry    reg;
  290.     char        s[256];
  291.     char        v[64];
  292.     midpViewWindow *win;
  293.     midpView    *view;
  294.  
  295.     reg.OpenKey(baseKey);
  296.     n = reg.ValueDWORD("NumViewWindows", 0);
  297.  
  298.     for ( i = 0; i < n; i++ )
  299.     {
  300.         sprintf(s, "%s\\ViewWindow%i", baseKey, i);
  301.  
  302.         if ( reg.KeyExists(s) )
  303.         {
  304.             reg.OpenKey(s);
  305.             reg.ValueString("ViewClass", "none", v, 63);
  306.  
  307.             view = viewList.FindView(v);
  308.             win = view->CreateViewWindow(®);
  309.         }
  310.     }
  311. }
  312.  
  313.  
  314.  
  315. void SaveViews(void)
  316. {
  317.     int         i;
  318.     Registry    reg;
  319.     char        s[256];
  320.     midpViewWindow *win;
  321.  
  322.     reg.OpenKey(baseKey);
  323.     reg.WriteDWORD("NumViewWindows", viewWindowList.NumWindows());
  324.  
  325.     for ( i = 0, win = viewWindowList.GetFirst(); win != NULL; i++,
  326.         win = viewWindowList.GetNext() )
  327.     {
  328.         sprintf(s, "%s\\ViewWindow%i", baseKey, i);
  329.  
  330.         if ( !reg.KeyExists(s) )
  331.             reg.CreateKey(s);
  332.         reg.OpenKey(s);
  333.  
  334.         win->SaveState(®);
  335.     }
  336. }
  337.  
  338.  
  339.  
  340.  
  341. void ReadRegistry(void)
  342. {
  343.     Registry    reg;
  344.  
  345.     if ( !reg.KeyExists(baseKey) )
  346.         reg.CreateKey(baseKey);
  347.     else
  348.         reg.OpenKey(baseKey);
  349.  
  350.     reg.ValueString("DefaultDirectory", "c:\\", defaultDir, MAX_PATH);
  351.     reg.ValueString("UnzipDirectory", "c:\\$$MidpNT$$", unzipDir, MAX_PATH);
  352.     viewsChildren = reg.ValueDWORD("OpenViewsAsChildWindows", 1);
  353. }
  354.  
  355.  
  356. void WriteRegistry(void)
  357. {
  358.     Registry    reg;
  359.  
  360.     reg.OpenKey("Software\\Sahara Surfers\\MidpNT");
  361.     reg.WriteString("DefaultDirectory", defaultDir);
  362.     reg.WriteString("UnzipDirectory", unzipDir);
  363.     reg.WriteDWORD("OpenViewsAsChildWindows", viewsChildren);
  364. }
  365.  
  366.  
  367. void DDEError(char *function, UINT error)
  368. {
  369.     char        msg[128];
  370.     sprintf(msg, "DDE Failure - %s: %u", function, error);
  371.     MessageBox(NULL, msg, "MidpNT Initialization error",
  372.         MB_OK | MB_ICONEXCLAMATION);
  373.     CloseMIDAS();
  374.     ExitProcess(17);
  375. }
  376.  
  377.  
  378.  
  379. HDDEDATA CALLBACK DdeServerCallback(
  380.     UINT  uType,    // transaction type
  381.     UINT  uFmt,    // clipboard data format
  382.     HCONV  hconv,    // handle of the conversation
  383.     HSZ  hsz1,    // handle of a string
  384.     HSZ  hsz2,    // handle of a string
  385.     HDDEDATA  hdata,    // handle of a global memory object
  386.     DWORD  dwData1,    // transaction-specific data
  387.     DWORD  dwData2     // transaction-specific data
  388.    )
  389. {
  390.     int         len;
  391.     char        *str;
  392.  
  393.     uType = uType;
  394.     uFmt = uFmt;
  395.     hconv = hconv;
  396.     hsz1 = hsz1;
  397.     hsz2 = hsz2;
  398.     hdata = hdata;
  399.     dwData1 = dwData1;
  400.     dwData2 = dwData2;
  401.  
  402.     switch ( uType )
  403.     {
  404.         case XTYP_CONNECT:
  405.             len = DdeQueryString(ddeInstance, hsz1, NULL, 0, CP_WINANSI);
  406.             if ( len == 0 )
  407.                 Panic("DdeServerCallback: Topic string length 0");
  408.             str = new char[len+1];
  409.             if ( !DdeQueryString(ddeInstance, hsz1, str, len+1, CP_WINANSI) )
  410.                 Panic("DdeServerCallback: DdeQueryString() failed");
  411.  
  412.             if ( !memcmp(str, "PlayFile:", 9) )
  413.             {
  414.                 if ( strlen(str) > 9 )
  415.                 {
  416. //                    AddTextLine(str);
  417.                     PlayFile(str+9);
  418.                 }
  419.             }
  420.             else
  421.                 Panic("DdeServerCallback: Bad topic");
  422.  
  423.             return (HDDEDATA) TRUE;
  424.     }
  425.  
  426.     return (HDDEDATA) 0L;
  427. }
  428.  
  429.  
  430.  
  431. void StartDDEServer(void)
  432. {
  433.     UINT        ddeError;
  434.     HSZ         strHandle;
  435.  
  436.     if ( (ddeError = DdeInitialize(&ddeInstance, DdeServerCallback,
  437.         APPCLASS_STANDARD, 0)) !=
  438.         DMLERR_NO_ERROR )
  439.         DDEError("Server DdeInitialize", ddeError);
  440.  
  441.     ddeInit = 1;
  442.  
  443.     if ( (strHandle = DdeCreateStringHandle(ddeInstance, "MidpNT",
  444.         CP_WINANSI)) == 0L )
  445.         DDEError("DdeCreateStringHandle", DdeGetLastError(ddeInstance));
  446.  
  447.     if ( DdeNameService(ddeInstance, strHandle, (HSZ) 0L, DNS_REGISTER) == 0 )
  448.         DDEError("DdeNameService", DdeGetLastError(ddeInstance));
  449.  
  450.     if ( !DdeFreeStringHandle(ddeInstance, strHandle) )
  451.         DDEError("DdeFreeStingHandle", DdeGetLastError(ddeInstance));
  452. }
  453.  
  454.  
  455.  
  456. HDDEDATA CALLBACK DdeClientCallback(
  457.     UINT  uType,    // transaction type
  458.     UINT  uFmt,    // clipboard data format
  459.     HCONV  hconv,    // handle of the conversation
  460.     HSZ  hsz1,    // handle of a string
  461.     HSZ  hsz2,    // handle of a string
  462.     HDDEDATA  hdata,    // handle of a global memory object
  463.     DWORD  dwData1,    // transaction-specific data
  464.     DWORD  dwData2     // transaction-specific data
  465.    )
  466. {
  467.     uType = uType;
  468.     uFmt = uFmt;
  469.     hconv = hconv;
  470.     hsz1 = hsz1;
  471.     hsz2 = hsz2;
  472.     hdata = hdata;
  473.     dwData1 = dwData1;
  474.     dwData2 = dwData2;
  475.  
  476.     return (HDDEDATA) 0L;
  477. }
  478.  
  479.  
  480.  
  481. int PlayDDE(char *fileName)
  482. {
  483.     char        *str;
  484.     HSZ         server, topic;
  485.     HCONV       conversation;
  486.     UINT        ddeError;
  487.     int         val;
  488.     static DWORD       ddeInstance;
  489.     char        *dummy;
  490.  
  491.     if ( strlen(fileName) )
  492.     {
  493.         str = new char[_MAX_PATH + 10];
  494.         strcpy(str, "PlayFile:");
  495.         /*
  496.         if ( _fullpath(str+9, fileName, _MAX_PATH) == NULL )
  497.             Panic("PlayDDE(): _fullpath failed");
  498.         */
  499.         if ( GetFullPathName(fileName, _MAX_PATH, str+9, &dummy) == 0 )
  500.             Panic("PlayDDE(): GetFullPathName() failed");
  501.     }
  502.     else
  503.         str = "PlayFile:";
  504.  
  505.     if ( (ddeError = DdeInitialize(&ddeInstance, DdeClientCallback,
  506.         APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0)) !=
  507.         DMLERR_NO_ERROR )
  508.         DDEError("Client DdeInitialize", ddeError);
  509.  
  510.     ddeInit = 1;
  511.  
  512.     if ( (server = DdeCreateStringHandle(ddeInstance, "MidpNT",
  513.         CP_WINANSI)) == 0L )
  514.         DDEError("DdeCreateStringHandle", DdeGetLastError(ddeInstance));
  515.  
  516.     if ( (topic = DdeCreateStringHandle(ddeInstance, str,
  517.         CP_WINANSI)) == 0L )
  518.         DDEError("DdeCreateStringHandle", DdeGetLastError(ddeInstance));
  519.  
  520.     if ( (conversation = DdeConnect(ddeInstance, server, topic, NULL)) == 0L )
  521.     {
  522.         ddeError = DdeGetLastError(ddeInstance);
  523.         if ( ddeError == DMLERR_NO_CONV_ESTABLISHED )
  524.             val = 0;
  525.         else
  526.             DDEError("DdeConnect", ddeError);
  527.     }
  528.     else
  529.     {
  530.         val = 1;
  531.  
  532.         if ( !DdeDisconnect(conversation) )
  533.             DDEError("DdeDisconnect", DdeGetLastError(ddeInstance));
  534.     }
  535.  
  536.     if ( !DdeFreeStringHandle(ddeInstance, server) )
  537.         DDEError("DdeFreeStingHandle", DdeGetLastError(ddeInstance));
  538.     if ( !DdeFreeStringHandle(ddeInstance, topic) )
  539.         DDEError("DdeFreeStingHandle", DdeGetLastError(ddeInstance));
  540.  
  541.     DdeUninitialize(ddeInstance);
  542.     ddeInit = 0;
  543.  
  544.     return val;
  545. }
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553. void Panic(char *message)
  554. {
  555.     MessageBox(NULL, message, "MIDP PANIC",
  556.         MB_OK | MB_ICONEXCLAMATION);
  557.     CloseMIDAS();
  558.     if ( ddeInit )
  559.         DdeUninitialize(ddeInstance);
  560.     ExitProcess(1);
  561. }
  562.  
  563.  
  564.  
  565. char *FileNameFilters =
  566.     "All Modules\0*.mod;*.s3m;*.xm;*.mdz;*.s3z;*.xmz\0"
  567.     "All Files\0*.*\0"
  568.     "Unpacked Modules\0*.mod;*.s3m;*.xm\0"
  569.     "Packed Modules\0*.mdz;*.s3z;*.xmz;*.zip\0"
  570.     "\0\0";
  571.  
  572.  
  573. char *GetFileName(char *windowTitle)
  574. {
  575.     static OPENFILENAME *ofn = NULL;
  576.     DWORD       error;
  577.  
  578.     if ( ofn == NULL )
  579.     {
  580.         if ( (ofn = (OPENFILENAME*) malloc(sizeof(OPENFILENAME))) == NULL )
  581.             return NULL;
  582.  
  583.         ofn->lStructSize = sizeof(OPENFILENAME);
  584.         ofn->hwndOwner = 0;
  585.         ofn->hInstance = 0;
  586.         ofn->lpstrFilter = (LPCSTR) FileNameFilters;
  587.         ofn->lpstrCustomFilter = NULL;
  588.         ofn->nMaxCustFilter = 0;
  589.         ofn->nFilterIndex = 1;
  590.         if ( (ofn->lpstrFile = (char*) malloc(1024)) == NULL )
  591.         {
  592.             ofn = NULL;
  593.             return NULL;
  594.         }
  595.         memset(ofn->lpstrFile, 0, 1024);
  596.         ofn->nMaxFile = 1023;
  597.         ofn->lpstrFileTitle = NULL;
  598.         ofn->nMaxFileTitle = 0;
  599.         ofn->lpstrInitialDir = defaultDir;  //!
  600.         ofn->lpstrTitle = windowTitle;
  601.         ofn->nFileOffset = 0;
  602.         ofn->nFileExtension = 0;
  603.         ofn->lpstrDefExt = 0;
  604.         ofn->Flags = OFN_EXPLORER;
  605.     }
  606.     else
  607.         ofn->lpstrInitialDir = NULL;
  608.  
  609.     ofn->lpstrTitle = windowTitle;
  610.  
  611.     if ( GetOpenFileName(ofn) == FALSE )
  612.     {
  613.         error = CommDlgExtendedError();
  614.         return NULL;
  615.     }
  616.  
  617.     return ofn->lpstrFile;
  618. }
  619.  
  620.  
  621. void ShowTextBottom(void)
  622. {
  623.     int         firstVisible;
  624.     int         lines;
  625.     int         newFirst;
  626.     int         textAreaHeight;
  627.     int         visibleLines;
  628.     HFONT       oldFont, font;
  629.     HDC         hdc;
  630.     TEXTMETRIC  textMetric;
  631.  
  632.     font = (HFONT) SendMessage(editWinHandle, WM_GETFONT, 0, 0);
  633.     firstVisible = (int) SendMessage(editWinHandle, EM_GETFIRSTVISIBLELINE, 0, 0);
  634.     lines = (int) SendMessage(editWinHandle, EM_GETLINECOUNT, 0, 0);
  635.     textAreaHeight = editHeight - GetSystemMetrics(SM_CYHSCROLL);
  636.  
  637.     hdc = GetDC(editWinHandle);
  638.     oldFont = SelectObject(hdc, font);
  639.     if ( GetTextMetrics(hdc, &textMetric) == FALSE )
  640.         return; /* FIXME */
  641.     SelectObject(hdc, oldFont);
  642.  
  643.     if ( textMetric.tmHeight > 0 )
  644.         visibleLines = textAreaHeight / textMetric.tmHeight;
  645.     else
  646.         visibleLines = 1;
  647.  
  648.     newFirst = lines - visibleLines - 1;
  649.     if ( newFirst < 0 )
  650.         newFirst = 0;
  651.     if ( newFirst > (lines-1) )
  652.         newFirst = lines-1;
  653.  
  654.     SendMessage(editWinHandle, EM_LINESCROLL, 0, newFirst - firstVisible);
  655. }
  656.  
  657.  
  658.  
  659.  
  660. void BuildText(void)
  661. {
  662.     int         i;
  663.  
  664.     text[0] = 0;
  665.     for ( i = 0; i < numLines; i++ )
  666.     {
  667.         strcat(text, textLines[i]);
  668.         strcat(text, "\r\n");
  669.     }
  670. }
  671.  
  672.  
  673.  
  674. void AddTextLine(char *textLine)
  675. {
  676.     int         i;
  677.     char        *temp;
  678.  
  679.     if ( numLines == NUMLINES )
  680.     {
  681.         temp = textLines[0];
  682.         for ( i = 0; i < (NUMLINES - 1); i++ )
  683.             textLines[i] = textLines[i+1];
  684.         textLines[NUMLINES-1] = temp;
  685.         numLines--;
  686.     }
  687.  
  688.     strncpy(textLines[numLines], textLine, MAXLINE);
  689.     numLines++;
  690.  
  691.     BuildText();
  692.  
  693.     SendMessage(editWinHandle, WM_SETREDRAW, (WPARAM) FALSE, 0);
  694.     SendMessage(editWinHandle, WM_SETTEXT, 0, (LPARAM) text);
  695.     ShowTextBottom();
  696.     SendMessage(editWinHandle, WM_SETREDRAW, (WPARAM) TRUE, 0);
  697.     InvalidateRect(editWinHandle, NULL, FALSE);
  698.     UpdateWindow(editWinHandle);
  699. }
  700.  
  701.  
  702.  
  703.  
  704. void InitText(void)
  705. {
  706.     int         i;
  707.  
  708.     text = (char*) malloc(NUMLINES * (MAXLINE+1));
  709.     text[0] = 0;
  710.  
  711.     for ( i = 0; i < NUMLINES; i++ )
  712.     {
  713.         textLines[i] = (char*) malloc(MAXLINE+1);
  714.         textLines[i][0] = 0;
  715.     }
  716. }
  717.  
  718.  
  719.  
  720. #define NUMMIXRATES 8
  721. int             mixRates[NUMMIXRATES] =
  722.         { 8000, 11025, 16000, 22050, 28000, 32000, 38000, 44100 };
  723.  
  724. BOOL CALLBACK SoundOptionsDialogProc(HWND hwnd, UINT message, WPARAM wparam,
  725.     LPARAM lparam)
  726. {
  727.     char        strBuffer[32];
  728.     int         i;
  729.  
  730.     lparam = lparam;                    // get rid of a stupid warning
  731.  
  732.     switch ( message )
  733.     {
  734.         case WM_INITDIALOG:
  735.             for ( i = 0; i < NUMMIXRATES; i++ )
  736.             {
  737.                 itoa(mixRates[i], strBuffer, 10);
  738.                 SendDlgItemMessage(hwnd, SOUNDOPTIONS_MIXRATE, CB_ADDSTRING,
  739.                     0, (LPARAM) strBuffer);
  740.             }
  741.             SendDlgItemMessage(hwnd, SOUNDOPTIONS_STEREO, BM_SETCHECK,
  742.                 (WPARAM) stereo, 0);
  743.             SendDlgItemMessage(hwnd, SOUNDOPTIONS_8BIT, BM_SETCHECK,
  744.                 (WPARAM) force8bit, 0);
  745.  
  746.             for ( i = 0; i < NUMMIXRATES; i++ )
  747.             {
  748.                 if ( mixRates[i] == mixRate )
  749.                 {
  750.                     SendDlgItemMessage(hwnd, SOUNDOPTIONS_MIXRATE,
  751.                         CB_SETCURSEL, i, 0);
  752.                     break;
  753.                 }
  754.             }
  755.  
  756.             itoa(500, strBuffer, 10);
  757.             SendDlgItemMessage(hwnd, SOUNDOPTIONS_BUFFERSIZE, WM_SETTEXT, 0,
  758.                 (LPARAM) strBuffer);
  759.  
  760.             itoa(16, strBuffer, 10);
  761.             SendDlgItemMessage(hwnd, SOUNDOPTIONS_BUFFERBLOCKS, WM_SETTEXT, 0,
  762.                 (LPARAM) strBuffer);
  763.  
  764.             return TRUE;
  765.  
  766.         case WM_COMMAND:
  767.             switch ( LOWORD(wparam) )
  768.             {
  769.                 case IDOK:
  770.                     SendDlgItemMessage(hwnd, SOUNDOPTIONS_MIXRATE,
  771.                         WM_GETTEXT, 31, (LPARAM) strBuffer);
  772.                     if ( atoi(strBuffer) != 0 )
  773.                         mixRate = atoi(strBuffer);
  774.                     stereo = SendDlgItemMessage(hwnd, SOUNDOPTIONS_STEREO,
  775.                         BM_GETCHECK, 0, 0);
  776.                     force8bit = SendDlgItemMessage(hwnd,
  777.                         SOUNDOPTIONS_8BIT, BM_GETCHECK, 0, 0);
  778.  
  779.                     MIDASsetOption(MIDAS_OPTION_MIXRATE, mixRate);
  780.  
  781.                     if ( stereo )
  782.                     {
  783.                         if ( force8bit )
  784.                             MIDASsetOption(MIDAS_OPTION_OUTPUTMODE,
  785.                                 MIDAS_MODE_8BIT_STEREO);
  786.                         else
  787.                             MIDASsetOption(MIDAS_OPTION_OUTPUTMODE,
  788.                                 MIDAS_MODE_16BIT_STEREO);
  789.                     }
  790.                     else
  791.                     {
  792.                         if ( force8bit )
  793.                             MIDASsetOption(MIDAS_OPTION_OUTPUTMODE,
  794.                                 MIDAS_MODE_8BIT_MONO);
  795.                         else
  796.                             MIDASsetOption(MIDAS_OPTION_OUTPUTMODE,
  797.                                 MIDAS_MODE_16BIT_MONO);
  798.                     }
  799.  
  800.                     SendDlgItemMessage(hwnd, SOUNDOPTIONS_BUFFERSIZE,
  801.                         WM_GETTEXT, 31, (LPARAM) strBuffer);
  802.                     if ( atoi(strBuffer) != 0 )
  803.                         MIDASsetOption(MIDAS_OPTION_MIXBUFLEN,
  804.                             atoi(strBuffer));
  805.  
  806.                     SendDlgItemMessage(hwnd, SOUNDOPTIONS_BUFFERBLOCKS,
  807.                         WM_GETTEXT, 31, (LPARAM) strBuffer);
  808.                     if ( atoi(strBuffer) != 0 )
  809.                         MIDASsetOption(MIDAS_OPTION_MIXBUFBLOCKS,
  810.                             atoi(strBuffer));
  811.  
  812.                     EndDialog(hwnd, 0);
  813.                     return TRUE;
  814.  
  815.                 case IDCANCEL:
  816.                     EndDialog(hwnd, 0);
  817.                     return TRUE;
  818.             }
  819.     }
  820.  
  821.     return FALSE;
  822. }
  823.  
  824.  
  825.  
  826. void SoundOptions(void)
  827. {
  828.     DialogBox(instance, "SOUNDOPTIONS", mainWinHandle, (DLGPROC)
  829.         &SoundOptionsDialogProc);
  830. }
  831.  
  832.  
  833. BOOL CALLBACK PreferencesDialogProc(HWND hwnd, UINT message, WPARAM wparam,
  834.     LPARAM lparam)
  835. {
  836.     lparam = lparam;                    // get rid of a stupid warning
  837.  
  838.     switch ( message )
  839.     {
  840.         case WM_INITDIALOG:
  841.             SendDlgItemMessage(hwnd, PREFERENCES_DEFAULTDIR, WM_SETTEXT,
  842.                 0, (LPARAM) defaultDir);
  843.             SendDlgItemMessage(hwnd, PREFERENCES_UNZIPDIR, WM_SETTEXT,
  844.                 0, (LPARAM) unzipDir);
  845.             SendDlgItemMessage(hwnd, PREFERENCES_VIEWSCHILDREN, BM_SETCHECK,
  846.                 (WPARAM) viewsChildren, 0);
  847.             return TRUE;
  848.  
  849.         case WM_COMMAND:
  850.             switch ( LOWORD(wparam) )
  851.             {
  852.                 case IDOK:
  853.                     SendDlgItemMessage(hwnd, PREFERENCES_DEFAULTDIR,
  854.                         WM_GETTEXT, MAX_PATH - 1, (LPARAM) defaultDir);
  855.                     SendDlgItemMessage(hwnd, PREFERENCES_UNZIPDIR,
  856.                         WM_GETTEXT, MAX_PATH - 1, (LPARAM) unzipDir);
  857.                     viewsChildren = SendDlgItemMessage(hwnd,
  858.                         PREFERENCES_VIEWSCHILDREN, BM_GETCHECK, 0, 0);
  859.                     EndDialog(hwnd, 0);
  860.                     return TRUE;
  861.  
  862.                 case IDCANCEL:
  863.                     EndDialog(hwnd, 0);
  864.                     return TRUE;
  865.             }
  866.     }
  867.  
  868.     return FALSE;
  869. }
  870.  
  871.  
  872.  
  873. void PlayFile(char *fileName)
  874. {
  875.     if ( module != NULL )
  876.     {
  877.         StopFreeModule(module);
  878.         module = NULL;
  879.     }
  880.  
  881.     if ( IsArchive(fileName) )
  882.     {
  883.         module = LoadArchive(fileName);
  884.  
  885.         if ( module != NULL )
  886.             PlayModule(module);
  887.     }
  888.     else
  889.     {
  890.         module = LoadModule(fileName);
  891.  
  892.         if ( module != NULL )
  893.             PlayModule(module);
  894.     }
  895.  
  896.     viewWindowList.SongChanged();
  897. }
  898.  
  899.  
  900. void RestoreMainWindow(void)
  901. {
  902.     Registry    reg;
  903.  
  904.     reg.OpenKey(baseKey);
  905.  
  906.     if ( reg.ValueExists("MainWindowX") )
  907.     {
  908.         mainWinX = reg.ValueDWORD("MainWindowX", 100);
  909.         mainWinY = reg.ValueDWORD("MainWindowY", 100);
  910.         mainWinWidth = reg.ValueDWORD("MainWindowWidth", 200);
  911.         mainWinHeight = reg.ValueDWORD("MainWindowHeight", 200);
  912.     }
  913.     else
  914.         mainWinX = mainWinY = mainWinWidth = mainWinHeight = CW_USEDEFAULT;
  915. }
  916.  
  917.  
  918. void SaveMainWindow(void)
  919. {
  920.     Registry    reg;
  921.     RECT        rect;
  922.  
  923.     reg.OpenKey(baseKey);
  924.  
  925.     GetWindowRect(mainWinHandle, &rect);
  926.     reg.WriteDWORD("MainWindowX", rect.left);
  927.     reg.WriteDWORD("MainWindowY", rect.top);
  928.     reg.WriteDWORD("MainWindowWidth", rect.right - rect.left);
  929.     reg.WriteDWORD("MainWindowHeight", rect.bottom - rect.top);
  930. }
  931.  
  932.  
  933.  
  934. void ListInstruments(void)
  935. {
  936.     char        str[256];
  937.     unsigned    i;
  938.     MIDASmoduleInfo moduleInfo;
  939.     MIDASinstrumentInfo instrumentInfo;
  940.  
  941.     if ( module != NULL )
  942.     {
  943.         MIDASgetModuleInfo(module, &moduleInfo);
  944.  
  945.         for ( i = 0; i < moduleInfo.numInstruments; i++ )
  946.         {
  947.             MIDASgetInstrumentInfo(module, i, &instrumentInfo);
  948.             sprintf(str, "%02X: %s", i + 1, instrumentInfo.instName);
  949.             AddTextLine(str);
  950.         }
  951.     }
  952. }
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959. /****************************************************************************\
  960. *
  961. * Function:     LRESULT mainWindowProc(HWND hwnd, UINT message, WPARAM wparam,
  962. *                   LPARAM lparam);
  963. *
  964. * Description:  Main window message processing function
  965. *
  966. \****************************************************************************/
  967.  
  968. LRESULT CALLBACK mainWindowProc(HWND hwnd, UINT message, WPARAM wparam,
  969.     LPARAM lparam)
  970. {
  971.     char        *fileName;
  972.     int         i;
  973.     char        aboutText[256];
  974.     MIDASplayStatus playStatus;
  975.     MIDASmoduleInfo moduleInfo;
  976.  
  977.     switch ( message )
  978.     {
  979.         case WM_CREATE:
  980.             /* Create edit box for console text: */
  981.             editWinHandle = CreateWindow(
  982.                 "EDIT",                 /* Window class */
  983.                 NULL,                   /* Window title */
  984.                 WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_LEFT |
  985.                     ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL |
  986.                     ES_READONLY,
  987.                 0, 0, 0, 0,             /* set size in WM_SIZE message */
  988.                 hwnd,                   /* parent window */
  989.                 (HMENU) ID_EDIT,        /* edit control ID */
  990.                 instance,
  991.                 NULL);                  /* no window creation data */
  992.  
  993.             mainWinHandle = hwnd;
  994.  
  995.             editWidth = editHeight = 0;
  996.  
  997.             /* Initialize text: */
  998.             InitText();
  999.  
  1000. //            AddTextLine("MIDAS Module Player for Windows NT initialized");
  1001. //            AddTextLine("");
  1002.             AddTextLine("MIDAS Module Player for Windows NT");
  1003.             AddTextLine("Copyright 1996,1997 Petteri Kangaslampi");
  1004.             AddTextLine("Version " FULLVERSTR ", built " __DATE__ ".");
  1005.             AddTextLine("");
  1006.             sprintf(aboutText, "Using MIDAS Sound System v%s,",
  1007.                 MIDASgetVersionString());
  1008.             AddTextLine(aboutText);
  1009.             AddTextLine("Copyright 1996,1997 Housemarque Inc.");
  1010.  
  1011.             AddTextLine("");
  1012.  
  1013.             /* Set edit control text: */
  1014.             SendMessage(editWinHandle, WM_SETTEXT, 0, (LPARAM) text);
  1015.  
  1016.             InitMIDAS();
  1017.  
  1018.             AddTextLine("MIDAS Sound System initialized");
  1019.  
  1020.             if ( strlen(loadFileName) != 0 )
  1021.                 PlayFile(loadFileName);
  1022.  
  1023.             break;
  1024.  
  1025.         case WM_SIZE:
  1026.             /* Make the edit control the size of the window's client area: */
  1027.             MoveWindow(editWinHandle,
  1028.                 0, 0,           /* starting x- and y-coordinates */
  1029.                 LOWORD(lparam), /* width of client area          */
  1030.                 HIWORD(lparam), /* height of client area         */
  1031.                 TRUE);          /* repaint window                */
  1032.             editWidth = LOWORD(lparam);
  1033.             editHeight = HIWORD(lparam);
  1034.             ShowTextBottom();
  1035.             return 0;
  1036.  
  1037.         case WM_COMMAND:
  1038.             switch ( LOWORD(wparam) )
  1039.             {
  1040.                 case MENU_FILE_OPEN:
  1041.                     fileName = GetFileName("Open File");
  1042.                     if ( fileName != NULL )
  1043.                         PlayFile(fileName);
  1044.                     break;
  1045.  
  1046.                 case MENU_FILE_CLOSE:
  1047.                     if ( module != NULL )
  1048.                     {
  1049.                         StopFreeModule(module);
  1050.                         module = NULL;
  1051.                     }
  1052.                     viewWindowList.SongChanged();
  1053.                     break;
  1054.  
  1055.                 case MENU_FILE_EXIT:
  1056.                     DestroyWindow(hwnd);
  1057.                     break;
  1058.  
  1059.                 case MENU_OPTIONS_SOUND:
  1060.                     if ( module != NULL )
  1061.                     {
  1062.                         StopFreeModule(module);
  1063.                         module = NULL;
  1064.                     }
  1065.                     viewWindowList.SongChanged();
  1066.                     CloseMIDAS();
  1067.                     SoundOptions();
  1068.                     InitMIDAS();
  1069.                     break;
  1070.  
  1071.                 case MENU_VIEWS_SONGINFO:
  1072.                     songInfoView->CreateViewWindow();
  1073.                     break;
  1074.  
  1075.                 case MENU_VIEWS_INSTLIST:
  1076.                     instListView->CreateViewWindow();
  1077.                     break;
  1078.  
  1079.                 case MENU_PLAYING_NEXTPOSITION:
  1080.                     if ( module != NULL )
  1081.                     {
  1082.                         MIDASgetPlayStatus(&playStatus);
  1083.                         MIDASgetModuleInfo(module, &moduleInfo);
  1084.                         if ( playStatus.position < (moduleInfo.songLength-1) )
  1085.                             MIDASsetPosition(playStatus.position + 1);
  1086.                     }
  1087.                     break;
  1088.  
  1089.                 case MENU_PLAYING_PREVPOSITION:
  1090.                     if ( module != NULL )
  1091.                     {
  1092.                         MIDASgetPlayStatus(&playStatus);
  1093.                         MIDASgetModuleInfo(module, &moduleInfo);
  1094.                         if ( playStatus.position > 0 )
  1095.                             MIDASsetPosition(playStatus.position - 1);
  1096.                     }
  1097.                     break;
  1098.  
  1099.                 case MENU_PLAYING_CENTERCHANNELS:
  1100.                     if ( module != NULL )
  1101.                     {
  1102.                         MIDASgetModuleInfo(module, &moduleInfo);
  1103.                         for ( i = 0; i < (int) moduleInfo.numChannels; i++ )
  1104.                         {
  1105.                             /* Kluge: */
  1106.                             if ( !MIDASsetSamplePanning(
  1107.                                 (MIDASsamplePlayHandle) i + 1,
  1108.                                 MIDAS_PAN_MIDDLE))
  1109.                                 MIDASerror();
  1110.                         }
  1111.                     }
  1112.                     break;
  1113.  
  1114.                 case MENU_OPTIONS_PREFERENCES:
  1115.                     DialogBox(instance, "PREFERENCES", hwnd, (DLGPROC)
  1116.                         &PreferencesDialogProc);
  1117.                     break;
  1118.  
  1119.                 case MENU_HELP_ABOUT:
  1120.                     sprintf(aboutText, "MIDAS Module Player for "
  1121.                         "Windows NT\nCopyright 1996,1997 Petteri Kangaslampi\n"
  1122.                         "Version " FULLVERSTR ", built " __DATE__ ".\n\n"
  1123.                         "Using MIDAS Sound System v%s\n"
  1124.                         "Copyright 1996,1997 Housemarque Inc.",
  1125.                         MIDASgetVersionString());
  1126.                     MessageBox(mainWinHandle, aboutText, "About MidpNT",
  1127.                         MB_OK | MB_ICONINFORMATION);
  1128.                     break;
  1129.  
  1130.                 case MENU_OPTIONS_SAVE_WIN:
  1131.                     SaveViews();
  1132.                     SaveMainWindow();
  1133.                     break;
  1134.  
  1135.                 case MENU_OPTIONS_RESTORE_WIN:
  1136.                     RestoreViews();
  1137.                     RestoreMainWindow();
  1138.                     break;
  1139.  
  1140.                 case MENU_PLAYING_LIST_INSTRUMENTS:
  1141.                     ListInstruments();
  1142.                     break;
  1143.             }
  1144.             break;
  1145.  
  1146.         case WM_DESTROY:
  1147.             CloseMIDAS();
  1148.             PostQuitMessage(0);
  1149.             break;
  1150.  
  1151.         default:
  1152.             return(DefWindowProc(hwnd, message, wparam, lparam));
  1153.     }
  1154.  
  1155.     return 0;
  1156. }
  1157.  
  1158.  
  1159.  
  1160. /*
  1161.  * $Log: MidpNT.cpp $
  1162.  * Revision 1.15  1997/01/25 13:17:44  pekangas
  1163.  * Rewrote archive support, added an icon
  1164.  *
  1165.  * Revision 1.14  1997/01/17 17:51:53  pekangas
  1166.  * Fixed a Visual C warning
  1167.  *
  1168.  * Revision 1.13  1997/01/17 17:41:35  pekangas
  1169.  * Text is also added to main window when in minimal UI mode
  1170.  * (it's not usually visible though)
  1171.  *
  1172.  * Revision 1.12  1997/01/17 00:08:23  pekangas
  1173.  * Added minimal UI mode - command line switch "-m"
  1174.  *
  1175.  * Revision 1.11  1997/01/14 22:25:11  pekangas
  1176.  * Finally fixed (?) all command line arguments with spaces
  1177.  *
  1178.  * Revision 1.10  1997/01/14 20:47:40  pekangas
  1179.  * Fixed channel centering (a stupid off-by-one error)
  1180.  *
  1181.  * Revision 1.9  1997/01/14 17:42:08  pekangas
  1182.  * Changed to use MIDAS DLL API
  1183.  *
  1184.  * Revision 1.8  1997/01/14 16:36:14  pekangas
  1185.  * Fixed support for files names with spaces as command line arguments
  1186.  *
  1187.  * Revision 1.7  1996/08/03 13:06:08  pekangas
  1188.  * Added 1 to "view instruments" instrument numbers
  1189.  *
  1190.  * Revision 1.6  1996/08/02  20:14:30  pekangas
  1191.  * Added View Instruments -function
  1192.  *
  1193.  * Revision 1.5  1996/07/16  20:20:01  pekangas
  1194.  * Added an error message if loading accelerators fails
  1195.  * (this happens if resources are not found)
  1196.  *
  1197.  * Revision 1.4  1996/07/16  19:11:59  pekangas
  1198.  * Fixed WinMain definition for Visual C
  1199.  *
  1200.  * Revision 1.3  1996/07/04  17:48:41  pekangas
  1201.  * Converted to LFs
  1202.  *
  1203. */